package com.xu.cloud.common.exception;

import com.xu.cloud.common.format.IMessageFormat;
import com.xu.cloud.common.format.JdkMessageFormat;
import com.xu.cloud.common.util.ApplicationContextUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;

/**
 * 基础异常信息类, 使用这个类来抛出基础异常
 *
 * @author xuguan
 * @see XuCloudException
 * @since 2024/1/23
 */
public class ErrorCodeInfo {

    public static final Logger log = LoggerFactory.getLogger(ErrorCodeInfo.class);

    private final String code;
    private final String message;
    private final IMessageFormat messageFormat = getMessageFormat();
    private static final List<IMessageFormat> messageFormatCache = new ArrayList<>(1);

    public ErrorCodeInfo(String code, String message) {
        this.code = code;
        this.message = message;
    }

    /**
     * 公共异常
     */
    public XuCloudException newException() {
        return new XuCloudException(code, message);
    }

    /**
     * 使用占位符的公共异常
     */
    public XuCloudException newExceptionWithArgs(String... args) {
        return new XuCloudException(code, messageFormat.format(message, args));
    }

    /**
     * 打印日志的公共异常
     */
    public XuCloudException newExceptionWithErrLog(String errLog, String... args) {
        log.error("ERROR LOG >>>>> {}", errLog);
        return new XuCloudException(code, messageFormat.format(message, args));
    }

    /**
     * 捕获异常
     */
    public XuCloudException catchException(Throwable cause) {
        return new XuCloudException(code, message, cause);
    }

    /**
     * 捕获异常, 使用占位符的公共异常
     */
    public XuCloudException catchExceptionWithArgs(Throwable cause, String... args) {
        return new XuCloudException(code, messageFormat.format(message, args), cause);
    }

    /**
     * 捕获异常, 打印日志的公共异常
     */
    public XuCloudException catchExceptionWithErrLog(String errLog, Throwable cause, String... args) {
        log.error("ERROR LOG >>>>> {}", errLog);
        return new XuCloudException(code, messageFormat.format(message, args), cause);
    }

    /**
     * 获取IMessageFormat消息格式化对象
     */
    private IMessageFormat getMessageFormat() {
        if (!messageFormatCache.isEmpty()) {
            return messageFormatCache.get(0);
        }

        IMessageFormat mf;
        try {
            mf = ApplicationContextUtil.getBean(IMessageFormat.class);
        } catch (Exception e) {
            log.error("Spring容器获取IMessageFormat类的bean失败", e);
            mf = new JdkMessageFormat();
        }
        messageFormatCache.add(mf);
        return mf;
    }
}
